#ifndef __M_TP_H__
#define __M_TP_H__
#include <iostream>
#include <queue>
#include <pthread.h>
#define MAX_THREAD 5

// 任务处理函数类型定义（返回bool表示执行状态，int为任务数据）
typedef bool (*handler_t)(int);

/***************************************
 * 线程任务类（ThreadTask）
 * 职责：封装任务数据和执行逻辑
 **************************************/
class ThreadTask {
private:
    int _data;          // 任务携带的数据
    handler_t _handler; // 任务处理函数指针

public:
    // 默认构造函数（空任务）
    ThreadTask():_data(-1), _handler(NULL) {}

    // 带参构造函数（初始化数据和处理函数）
    ThreadTask(int data, handler_t handler) {
        _data= data;
        _handler = handler;
    }

    // 设置任务内容
    void SetTask(int data, handler_t handler) {
        _data = data;
        _handler = handler;
    }

    // 执行任务（核心方法）
    void Run() {
        _handler(_data);  // 调用处理函数
    }
};

/***************************************
 * 线程池类（ThreadPool）
 * 职责：管理线程资源和任务调度
 **************************************/
class ThreadPool {
private:
    // 资源控制相关
    int _thread_max;     // 最大线程数
    int _thread_cur;     // 当前活跃线程数
    bool _tp_quit;       // 线程池退出标志

    // 任务队列相关
    std::queue<ThreadTask *> _task_queue; // 任务队列（存储任务指针）
    
    // 同步机制相关
    pthread_mutex_t _lock;  // 互斥锁
    pthread_cond_t _cond;   // 条件变量

    /***************************************
     * 私有方法（内部工具函数）
     **************************************/
    // 加锁队列
    void LockQueue() {
        pthread_mutex_lock(&_lock);
    }

    // 解锁队列
    void UnLockQueue() {
        pthread_mutex_unlock(&_lock);
    }

    // 唤醒单个线程
    void WakeUpOne() {
        pthread_cond_signal(&_cond);  // 发送条件信号
    }

    // 唤醒所有线程
    void WakeUpAll() {
        pthread_cond_broadcast(&_cond);  // 广播条件信号
    }

    // 线程退出处理
    void ThreadQuit() {
        _thread_cur--;      // 活跃线程数减1
        UnLockQueue();       // 必须先解锁！
        pthread_exit(NULL);  // 结束当前线程
    }

    // 线程等待条件变量
    void ThreadWait(){
        if (_tp_quit) {      // 检查退出标志
            ThreadQuit();    // 若需要退出则结束线程
        }
        pthread_cond_wait(&_cond, &_lock);  // 阻塞等待条件变量
    }

    // 判断任务队列是否为空
    bool IsEmpty() {
        return _task_queue.empty();
    }

    /***************************************
     * 线程入口函数（静态方法）
     **************************************/
    static void *thr_start(void *arg) {
        ThreadPool *tp = (ThreadPool*)arg;  // 获取线程池实例
        
        // 线程主循环
        while(1) {
            tp->LockQueue();
            
            // 关键点：必须使用while而非if判断空队列
            while(tp->IsEmpty()) {  
                tp->ThreadWait();  // 等待任务到来
            }
            
            // 取出任务
            ThreadTask *tt;
            tp->PopTask(&tt);  // 存在风险：未检查队列空直接pop
            
            tp->UnLockQueue();
            
            // 执行任务（在解锁后执行，减少锁占用时间）
            tt->Run();
            delete tt;  // 释放任务内存
        }
        return NULL;
    }

public:
    /***************************************
     * 公共接口
     **************************************/
    // 构造函数（初始化线程数）
    ThreadPool(int max=MAX_THREAD)
        :_thread_max(max), 
         _thread_cur(max),
         _tp_quit(false) 
    {
        pthread_mutex_init(&_lock, NULL);  // 初始化互斥锁
        pthread_cond_init(&_cond, NULL);   // 初始化条件变量
    }

    // 析构函数（清理资源）
    ~ThreadPool() {
        pthread_mutex_destroy(&_lock);  // 销毁互斥锁
        pthread_cond_destroy(&_cond);   // 销毁条件变量
    }

    // 初始化线程池（创建线程）
    bool PoolInit() {
        pthread_t tid;
        for (int i = 0; i < _thread_max; i++) {
            int ret = pthread_create(&tid, NULL, thr_start, this);
            if (ret != 0) {
                std::cout<<"create pool thread error\n";
                return false;
            }
        }
        return true;
    }

    // 添加任务到队列（生产者接口）
    bool PushTask(ThreadTask *tt) {
        LockQueue();
        if (_tp_quit) {        // 如果线程池已关闭
            UnLockQueue();
            return false;
        }
        _task_queue.push(tt);  // 任务入队
        WakeUpOne();           // 唤醒一个工作线程
        UnLockQueue();
        return true;
    }

    // 从队列取出任务（消费者接口）
    bool PopTask(ThreadTask **tt) {
        /* 问题点：未检查队列空直接pop，可能导致崩溃 */
        *tt = _task_queue.front();  // 获取队首任务
        _task_queue.pop();          // 移除任务
        return true;
    }

    // 关闭线程池
    bool PoolQuit() {
        LockQueue();
        _tp_quit = true;  // 设置退出标志
        UnLockQueue();
        
        // 等待所有线程退出（轮询方式）
        while(_thread_cur > 0) {
            WakeUpAll();      // 唤醒所有线程
            usleep(1000);     // 休眠1ms（可能不够高效）
        }
        return true;
    }
};

#endif

/*main.cpp*/
bool handler(int data) {
    srand(time(NULL));
    int n = rand() % 5;
    printf("Thread: %p Run Tast: %d--sleep %d sec\n", 
           pthread_self(), data, n);
    sleep(n);
    return true;
}

int main() {
    int i;
    ThreadPool pool;     // 创建线程池（默认5线程）
    pool.PoolInit();     // 初始化线程
    
    // 提交10个任务
    for (i = 0; i < 10; i++) {
        ThreadTask *tt = new ThreadTask(i, handler);
        pool.PushTask(tt);
    }
    
    pool.PoolQuit();     // 关闭线程池
    return 0;
}